package cn.tedu.v1_1;

import java.io.*;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;

/**
 * 聊天室 Version 1.1
 * 服务器 功能：1.服务器申请端口号：软件具备端口号
 *            2.在start方法中；等待客户端链接，返回socket
 *                           IO读入
 *      【新增】3.所有服务器端异常，全部捕获，明确提示
 *            4.关闭serverSocket
 *            5.知道对方IP---start方法---accept---返回客户端连接
 *            6.在服务器添加多人聊天
 *  测试：自己链接自己  测试
 *  1个客户端连接一个服务器---accept【卡住】只能接受一个 接while(true){}
 *   无数客户端连接同一个服务器--多线程并发  2.1创建线程类--服务器端处理各个客户端线程类--CS
 *
 *  主方法下创建内部类:private class CS implements Runnable{}
 *
 *  测试 ping 通 对方IP
 */
public class Server {
    private ServerSocket serverSocket;
    public Server(){
        try {
            serverSocket=new ServerSocket(886);
            //BindException   端口号已经被占用
        } catch (BindException e){
            System.out.println("请检查端口号，被傻小子占用~");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void start() {
        while (true) {
            Socket socket=null;
            String ip=null;
            try {
                while(true){
                System.out.println("等待客户端连接");
                socket = serverSocket.accept();
                //getInetAddress() 返回Address对象，表示远方IP地址
                //具体IP地址 getHostAddress,将远方地址转换为字符串,没连接返回null
                System.out.println("一个傻小子连接上了");
                ip = socket.getInetAddress().getHostAddress();
                System.out.println("客户端" + ip + "连接上了");

                //无限循环--等待接受客户端发过来的socket
                //利用多线程并发---无限次客户端连接正确读入
                //接入一个客户端 正确读入  【服务器发来socket,接待一个】
                //创建多线程并发
                CS cs=new CS(socket);
                Thread t1=new Thread(cs);
                t1.start();
            }
            } catch (IOException e) {
                        System.out.println("你鼐·奈德");
            }finally {
                try {
                    socket.close();
                } catch (IOException e) {
                    System.out.println("啊哈哈");
                }
            }
        }

    }
    public static void main(String[] args) throws IOException {
        Server server=new Server();
        server.start();
    }
    //2.1在主方法下创建内部类:服务器端处理各个客户端线程类  CS
    private class CS implements Runnable {
        //2.3 线程需要有socket对象  定义一个私有化属性:Socket
        //  服务器端一旦有一个客户端连接上服务器---返回Socket
        private Socket socket;

        public CS(Socket s){//线程传入客户端socket
            this.socket=s; //线程中 s  创建线程:socket,客户端发来
            //客户端给服务器发来 s  接收一个给当前Socket
            //可以得知谁连上个人,每次说话时
            //服务器正常读入
        }
        //2.2 通过线程运行状态:读取客户端发来文本
        public void run() {
            BufferedReader br = null;
           // Socket socket = null;
            try {
                InputStream is = socket.getInputStream();
                InputStreamReader isr =
                        new InputStreamReader(is, "UTF8");
                br = new BufferedReader(isr);
                //服务器端：一直读
                while (true) {
                    String str = br.readLine();
                    System.out.println("傻小子：" + str);
                }
            } catch (UnsupportedEncodingException e) {
                System.out.println("请检查客户端/服务器端编码集:他妈的不一致~");
            } catch (SocketException e) {
                System.out.println("重置了");
            } catch (IOException e) {
                System.out.println("客户端链接失78效了");
            } finally {
                if (br != null)
                    try {
                        br.close();
                    } catch (IOException e) {
                           System.out.println("读入流断78链接了");
                    }
                try {
                    socket.close();
                } catch (IOException e) {
                    System.out.println("客户端断78了");
                }
            }
        }
    }
}
